using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using WikiApp.Models;
using WikiApp.Pages;

namespace WikiApp
{
    public abstract class BaseContentPage : Page
    {
        public static readonly DependencyProperty BackCommandProperty =
            DependencyProperty.Register("BackCommand", typeof(ICommand), typeof(BaseContentPage));

        public ICommand BackCommand
        {
            get => (ICommand)GetValue(BackCommandProperty);
            set => SetValue(BackCommandProperty, value);
        }

        protected BaseContentPage()
        {
            BackCommand = new RelayCommand(_ => NavigationService.GoBack());
        }

        protected abstract string ContentFolder { get; }
        protected abstract string YamlFileName { get; }

        public static Page CreatePage(string title, string yamlFileName, string pageType)
        {
            return new TemplatePage(title, yamlFileName, pageType);
        }

        protected virtual void LoadContent()
        {
            try
            {
                var yamlPath = Path.Combine(ContentFolder, YamlFileName);
                if (!File.Exists(yamlPath))
                {
                    MessageBox.Show($"YAML file not found at: {yamlPath}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                var yaml = File.ReadAllText(yamlPath);
                var deserializer = new DeserializerBuilder()
                    .WithNamingConvention(CamelCaseNamingConvention.Instance)
                    .Build();
                var data = deserializer.Deserialize<CardData>(yaml);

                if (data?.Directory?.Root == null)
                {
                    MessageBox.Show("Directory structure is invalid", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                var treeView = FindName("FileTreeView") as TreeView;
                if (treeView == null)
                {
                    MessageBox.Show("FileTreeView not found", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                treeView.Items.Clear();
                var rootItem = CreateTreeViewItem(data.Directory.Root);
                treeView.Items.Add(rootItem);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error loading content: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        protected virtual void LoadVersions()
        {
            try
            {
                var yamlPath = Path.Combine(ContentFolder, YamlFileName);
                if (!File.Exists(yamlPath))
                {
                    MessageBox.Show($"YAML file not found at: {yamlPath}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                var yaml = File.ReadAllText(yamlPath);
                var deserializer = new DeserializerBuilder()
                    .WithNamingConvention(CamelCaseNamingConvention.Instance)
                    .Build();
                var data = deserializer.Deserialize<CardData>(yaml);

                if (data?.Versions == null)
                {
                    MessageBox.Show("No versions found", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                var versionButtonsPanel = FindName("VersionButtonsPanel") as StackPanel;
                var versionContentPanel = FindName("VersionContentPanel") as StackPanel;

                if (versionButtonsPanel == null || versionContentPanel == null)
                {
                    MessageBox.Show("Version panels not found", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                versionButtonsPanel.Children.Clear();
                versionContentPanel.Children.Clear();

                foreach (var version in data.Versions)
                {
                    var button = new Button
                    {
                        Content = $"版本 {version.Version}",
                        Margin = new Thickness(5),
                        Command = new RelayCommand(_ => ShowVersionContent(version, versionContentPanel))
                    };

                    versionButtonsPanel.Children.Add(button);

                    if (version.Version == "1.0")
                    {
                        ShowVersionContent(version, versionContentPanel);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error loading versions: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private TreeViewItem CreateTreeViewItem(DirectoryItem item)
        {
            var treeViewItem = new TreeViewItem
            {
                Header = item.Name,
                Tag = item
            };

            if (item.Items != null)
            {
                foreach (var child in item.Items)
                {
                    var childItem = CreateTreeViewItem(child);
                    treeViewItem.Items.Add(childItem);
                }
            }

            return treeViewItem;
        }

        private void ShowVersionContent(VersionContent content, StackPanel contentPanel)
        {
            contentPanel.Children.Clear();

            foreach (var step in content.Steps ?? new List<Step>())
            {
                var stepPanel = new StackPanel { Margin = new Thickness(10) };

                if (!string.IsNullOrEmpty(step.Description))
                {
                    var descriptionBlock = new TextBlock
                    {
                        Text = step.Description.Replace("### ", ""),
                        Style = (Style)FindResource("StepDescriptionStyle")
                    };
                    stepPanel.Children.Add(descriptionBlock);
                }

                if (step.Tasks != null)
                {
                    foreach (var task in step.Tasks)
                    {
                        var taskTextBlock = new TextBlock
                        {
                            Style = (Style)FindResource("TaskTextStyle"),
                            Margin = new Thickness(0, 0, 0, 5),
                            TextWrapping = TextWrapping.Wrap
                        };

                        var text = task.Text;
                        var parts = text.Split(new[] { '{', '}' }, StringSplitOptions.None);
                        var isSpecial = false;

                        foreach (var part in parts)
                        {
                            if (isSpecial)
                            {
                                var colonIndex = part.IndexOf(':');
                                if (colonIndex > 0)
                                {
                                    var specialText = part.Substring(0, colonIndex);
                                    var style = part.Substring(colonIndex + 1);

                                    var run = new Run(specialText);
                                    switch (style.ToLower())
                                    {
                                        case "code":
                                            var codeTextBlock = new TextBlock
                                            {
                                                Text = specialText,
                                                Foreground = System.Windows.Media.Brushes.Red,
                                                FontFamily = new System.Windows.Media.FontFamily("Consolas"),
                                                Background = System.Windows.Media.Brushes.WhiteSmoke,
                                                Padding = new Thickness(2, 1, 2, 1),
                                                VerticalAlignment = VerticalAlignment.Center
                                            };
                                            var border = new Border
                                            {
                                                BorderBrush = System.Windows.Media.Brushes.LightGray,
                                                BorderThickness = new Thickness(1),
                                                Child = codeTextBlock,
                                                Height = codeTextBlock.FontSize + 2,
                                                Margin = new Thickness(2, 0, 2, -4)
                                            };
                                            taskTextBlock.Inlines.Add(border);
                                            break;
                                        case "bold":
                                            run.FontWeight = FontWeights.Bold;
                                            taskTextBlock.Inlines.Add(run);
                                            break;
                                        case "italic":
                                            run.FontStyle = FontStyles.Italic;
                                            taskTextBlock.Inlines.Add(run);
                                            break;
                                    }
                                }
                                isSpecial = false;
                            }
                            else
                            {
                                if (part.Contains("[") && part.Contains("]") && part.Contains("(") && part.Contains(")"))
                                {
                                    var linkText = part.Substring(part.IndexOf("[") + 1, part.IndexOf("]") - part.IndexOf("[") - 1);
                                    var linkUrl = part.Substring(part.IndexOf("(") + 1, part.IndexOf(")") - part.IndexOf("(") - 1);
                                    
                                    var linkTextBlock = new TextBlock
                                    {
                                        Text = linkText,
                                        Foreground = System.Windows.Media.Brushes.Blue,
                                        TextDecorations = System.Windows.TextDecorations.Underline,
                                        Cursor = Cursors.Hand
                                    };
                                    linkTextBlock.MouseLeftButtonDown += (s, e) =>
                                    {
                                        try
                                        {
                                            Clipboard.SetText(linkUrl);
                                            MessageBox.Show("链接已复制", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                                        }
                                        catch (Exception ex)
                                        {
                                            MessageBox.Show($"复制链接失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                                        }
                                    };
                                    taskTextBlock.Inlines.Add(linkTextBlock);
                                }
                                else
                                {
                                    taskTextBlock.Inlines.Add(new Run(part));
                                }
                                isSpecial = true;
                            }
                        }

                        stepPanel.Children.Add(taskTextBlock);
                    }
                }

                if (step.Commands != null)
                {
                    foreach (var command in step.Commands)
                    {
                        var commandBorder = new Border
                        {
                            Style = (Style)FindResource("CommandBlockStyle")
                        };

                        var commandGrid = new Grid();
                        commandGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
                        commandGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

                        var commandBlock = new TextBlock
                        {
                            Text = command.Value,
                            Style = (Style)FindResource("CommandTextStyle")
                        };
                        Grid.SetColumn(commandBlock, 0);

                        var copyButton = new Button
                        {
                            Content = "Copy",
                            Margin = new Thickness(5, 0, 0, 0),
                            Command = new RelayCommand(_ => Clipboard.SetText(command.Value))
                        };
                        Grid.SetColumn(copyButton, 1);

                        commandGrid.Children.Add(commandBlock);
                        commandGrid.Children.Add(copyButton);
                        commandBorder.Child = commandGrid;
                        stepPanel.Children.Add(commandBorder);
                    }
                }

                contentPanel.Children.Add(stepPanel);
            }
        }

        protected virtual void FileItem_DoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (sender is TreeView treeView && treeView.SelectedItem is TreeViewItem item && item.Tag is DirectoryItem directoryItem)
            {
                try
                {
                    var codeContent = FindName("CodeContent") as TextBlock;
                    var lineNumbers = FindName("LineNumbers") as TextBlock;

                    if (codeContent != null)
                    {
                        codeContent.Text = directoryItem.Content ?? string.Empty;

                        if (lineNumbers != null)
                        {
                            var lines = (directoryItem.Content ?? string.Empty).Split('\n');
                            lineNumbers.Text = string.Join("\n", Enumerable.Range(1, lines.Length));
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error loading file: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        protected virtual void TreeViewItem_DoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (sender is TreeViewItem item)
            {
                item.IsExpanded = !item.IsExpanded;
                e.Handled = true;
            }
        }
    }

    public class RelayCommand : ICommand
    {
        private readonly Action<object?> _execute;
        private readonly Predicate<object?>? _canExecute;

        public RelayCommand(Action<object?> execute, Predicate<object?>? canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public bool CanExecute(object? parameter)
        {
            return _canExecute == null || _canExecute(parameter);
        }

        public void Execute(object? parameter)
        {
            _execute(parameter);
        }

        public event EventHandler? CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
} 